package com.hsy.swu.home.grade

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.room.Room
import com.google.android.material.tabs.TabLayout
import com.hsy.swu.MyConfig
import com.hsy.swu.databinding.DialogGradeBinding
import com.hsy.swu.databinding.DialogGradeItemBinding
import com.hsy.swu.databinding.FragmentGradeBinding
import com.hsy.swu.databinding.ItemGradeBinding
import com.hsy.swu.home.HomeFragmentViewModel
import com.hsy.swu.hsyutils.HsyDialog
import com.hsy.swu.hsyutils.HsyFragment
import com.hsy.swu.hsyutils.MActivityUtil
import com.hsy.swu.hsyutils.addItem
import com.hsy.swu.hsyutils.setFont
import com.hsy.swu.roomdb.AppDatabase
import com.hsy.swu.roomdb.GradeDao
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.time.LocalDate

class GradeFragment : HsyFragment<FragmentGradeBinding, HomeFragmentViewModel>() {
    private lateinit var gradeDao: GradeDao

    private var postYear = ""
    private var postSemester = ""
        set(value) {
            field = if (value == "1") "3" else if (value == "2") "12" else "16"
        }

    private var isNeedCreateUI = true

    override fun createViewModel(): HomeFragmentViewModel {
        return ViewModelProvider(requireActivity())[HomeFragmentViewModel::class.java]
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        if (isNeedCreateUI) {
            isNeedCreateUI = false
            gradeDao = Room.databaseBuilder(
                requireContext(),
                AppDatabase::class.java,
                "swu"
            ).build().gradeDao()

            initYearSelectBar()
            initSemesterSelectBar()
            initSelect()
        }
    }

    override fun onResume() {
        super.onResume()
        lifecycleScope.launch {
            getGradeFromRoomDBAndRefreshUI(postYear, postSemester)
        }
        mViewModel.mBinder?.getService()?.setGetGradeListener {
            if (isResumed) {
                lifecycleScope.launch {
                    getGradeFromRoomDBAndRefreshUI(postYear, postSemester)
                }
            }
        }
    }

    // onPause清空内容，使得下次跳转到当前 fragment的显示效果更加丝滑
    override fun onPause() {
        super.onPause()
        mBinding.linearLayoutGrade.removeAllViews()
    }

    private fun initYearSelectBar() {
        val year = LocalDate.now().year
        for (y in MyConfig.gradeYear..year) {
            mBinding.yearSelectBar.apply {
                newTab().apply {
                    text = "$y"
                    addTab(this)
                }
            }
        }
        mBinding.yearSelectBar.addOnTabSelectedListener(object :
            TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                mBinding.yearSelectBar.setFont() // 这里放 setFont是因为不能直接给 Tab设置字体，因为他不是 TextView，但是给根视图设置就能设置到他的字体
                postYear = tab?.text.toString()
                if (postYear.isNotEmpty() && postSemester.isNotEmpty()) { // 这里判空是因为初始化的时候先选年，这时候可能学期为空
                    lifecycleScope.launch {
                        getGradeFromRoomDBAndRefreshUI(postYear, postSemester)
                    }
                }
            }

            override fun onTabUnselected(tab: TabLayout.Tab?) {
            }

            override fun onTabReselected(tab: TabLayout.Tab?) {
            }
        })
    }

    private fun initSemesterSelectBar() {
        repeat(3) {
            mBinding.semesterSelectBar.apply {
                newTab().apply {
                    text = "${it + 1}"
                    addTab(this)
                }
            }
        }
        mBinding.semesterSelectBar.addOnTabSelectedListener(object :
            TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                mBinding.semesterSelectBar.setFont() // 这里放 setFont是因为不能直接给 Tab设置字体，因为他不是 TextView，但是给根视图设置就能设置到他的字体
                postSemester = tab?.text.toString()
                lifecycleScope.launch {
                    getGradeFromRoomDBAndRefreshUI(postYear, postSemester)
                }
            }

            override fun onTabUnselected(tab: TabLayout.Tab?) {
            }

            override fun onTabReselected(tab: TabLayout.Tab?) {
            }
        })
    }

    // 初始选中
    private fun initSelect() {
        mBinding.yearSelectBar.apply {
            val toSelectIndex = if (tabCount - 2 < 0) 0 else tabCount - 2
            selectTab(getTabAt(toSelectIndex))
        }
        val semester = if (LocalDate.now().month.value in 3..9) 2 else 1
        mBinding.semesterSelectBar.apply {
            selectTab(getTabAt(semester - 1))
        }
        postSemester = semester.toString()
    }

    private suspend fun getGradeFromRoomDBAndRefreshUI(
        year: String,
        semester: String
    ) {
        var gradeDBList: List<GradeModel>
        withContext(Dispatchers.IO) {
            gradeDBList = gradeDao.getAllByYearAndSemester(year, semester)
        }
        mBinding.linearLayoutGrade.removeAllViews()
        gradeDBList.forEach {
            mBinding.linearLayoutGrade.addGradeItem(it, layoutInflater)
        }

        if (gradeDBList.isNotEmpty()) {
            MActivityUtil.alphaAnimGoneLottieEmpty(mBinding.lottieEmpty)
        } else {
            MActivityUtil.alphaAnimVisibleLottieEmpty(mBinding.lottieEmpty)
        }
    }

    companion object {
        suspend fun LinearLayoutCompat.addGradeItem(
            gradeModel: GradeModel,
            layoutInflater: LayoutInflater
        ) {
            val itemBinding = ItemGradeBinding.inflate(layoutInflater, this, false)
            itemBinding.apply {
                tvName.text = gradeModel.name
                tvCredit.text = gradeModel.credit
                tvGrade.text = gradeModel.grade
                tvGradePoint.text = gradeModel.creditGradePoint
            }
            addItem(itemBinding)

            itemBinding.root.setOnClickListener {
                object : HsyDialog<DialogGradeBinding>(context, { mBinding, _ ->
                    mBinding.tvTopGradeName.text = gradeModel.name
                    mBinding.gradeLinearLayout.addDialogGradeItem(
                        gradeModel.teacher,
                        gradeModel.classification,
                        gradeModel.gradeDetail,
                        layoutInflater
                    )
                }) {}.show()
            }
            itemBinding.root.animate().scaleX(0f).scaleY(0f).setDuration(0L).start() // 先缩到最小
            delay(10) // 延迟达到动画效果
            MActivityUtil.scaleAnimOnShow(itemBinding.root)
        }

        private fun LinearLayoutCompat.addDialogGradeItem(
            teacher: String,
            classification: String,
            gradeDetail: String,
            layoutInflater: LayoutInflater
        ) {
            gradeDetail.split(",").forEach { // 详细信息添加完
                val itemBinding = DialogGradeItemBinding.inflate(layoutInflater, this, false)
                itemBinding.apply {
                    tvKey.text = it.split("-")[0]
                    tvValue.text = it.split("-")[1]
                }
                addItem(itemBinding)
            }
            val itemBinding1 = DialogGradeItemBinding.inflate(layoutInflater, this, false)
            itemBinding1.apply {
                tvKey.text = "教师"
                tvValue.text = teacher
            }
            addItem(itemBinding1)
            val itemBinding2 = DialogGradeItemBinding.inflate(layoutInflater, this, false)
            itemBinding2.apply {
                tvKey.text = "类型"
                tvValue.text = classification
            }
            addItem(itemBinding2) // 最后用这个 addItem加，来设置字体
        }
    }
}